//
//  TFSClient.swift
//  TFSClient
//
//  Created by Samuel Richard Magny on 2015-09-07.
//  Copyright (c) 2015 Samuel Richard Magny. All rights reserved.
//

import Cocoa
import SwiftTools

public class TFSClient: GitTfAdapterDelegate {

    
    
    
    
    
    
    
    //Get/Set
    //-----------------------------------
    public var workingDirectory:String {
        get{
            return self.gitTfAdapter.workingDirectory
        }
        set(directory) {
            self.gitTfAdapter.workingDirectory = directory
            self.gitClient.workingDirectory = directory
        }
    }
    
    public var projectDirectoryServerPath:String {
        get{
            return self.gitTfAdapter.getWorkingDirectoryServerPath()
        }
    }
    
    public var projectDirectoryServerUrl:String {
        get{
            return self.gitTfAdapter.getWorkingDirectoryServerUrl()
        }
    }
    
    public var username:String
    public var password:String
    public var email:String
    
    public var delegate:TFSClientDelegate?
        
    
    //Privates
    //-----------------------------------
    private let gitTfAdapter:GitTfAdapter
    private let gitClient:GitClient
    
    private var currentTFSCommand:TFSCommandType = TFSCommandType.None
    private var tfsCommandCompletion: ((Bool) -> Void)?
    
    //Inits
    //-----------------------------------
    public init(projectDirectory:String) {
        self.username = ""
        self.password = ""
        self.email = ""
        
        gitTfAdapter = GitTfAdapter(workingDirectory: projectDirectory)
        gitClient = GitClient(workingDirectory: projectDirectory)
        gitTfAdapter.delegate = self
    }
    
    public convenience init() {
        self.init(projectDirectory: "")
    }
    
    
    //Publics funcs
    //-----------------------------------
    public func pull(completionHandler:(withSuccess:Bool) -> ()) {
        if setCurrentCommand(TFSCommandType.Pull, completionHandler: completionHandler)
        {
            gitTfAdapter.pull()
        }
        
    }
    
    public func checkin(completionHandler:(withSuccess:Bool) -> ()) {
        if setCurrentCommand(TFSCommandType.Checkin, completionHandler: completionHandler)
        {
            gitTfAdapter.checkin()
        }
        
    }
    
    public func clone(serverUrl:String, serverPath: String, completionHandler:(withSuccess:Bool) -> ()) {
        if setCurrentCommand(TFSCommandType.Clone, completionHandler: completionHandler)
        {
            gitTfAdapter.clone(self.workingDirectory, serverUrl: serverUrl, serverProjectPath: serverPath)
        }
        
    }
    
    public func configure(serverUrl:String, serverPath: String, completionHandler:(withSuccess:Bool) -> ()) {
        if setCurrentCommand(TFSCommandType.Configure, completionHandler: completionHandler)
        {
            gitTfAdapter.configure(self.workingDirectory, serverUrl: serverUrl, serverProjectPath: serverPath)
        }
        
    }
    
    public func commit(comments:String, completionHandler:(withSuccess:Bool) -> ()) {
        //TODO: Implement completion handler
//        if setCurrentCommand(TFSCommandType.Commit, completionHandler: completionHandler)
//        {
        self.gitClient.commitStagedFiles(comments, author: self.username, email:self.email)
//        }
        
    }
    
    public func fetch(completionHandler:(withSuccess:Bool) -> ()) {
        if setCurrentCommand(TFSCommandType.Fetch, completionHandler: completionHandler)
        {
            self.gitTfAdapter.fetch()
        }
        
    }
    
    public func stageFile(file:TFSFile) -> TFSFile
    {
        return self.gitClient.stageFile(file)
    }
    
    public func stageFiles(files:Array<TFSFile>) -> Array<TFSFile>
    {
        return self.gitClient.stageFiles(files)
    }
    
    public func unStageFile(file:TFSFile) -> TFSFile
    {
        return self.gitClient.unStageFile(file)
    }
    
    public func unStageFiles(files:Array<TFSFile>) -> Array<TFSFile>
    {
        return self.gitClient.unStageFiles(files)
    }
    
    public func retreivePendingChangeFiles(completionHandler:(OrderedDictionary<String, TFSFile>)->())
    {
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority, 0)) {
            
            let files = self.gitClient.retreivePendingChangeFiles()
            completionHandler(files)
        }
    }
    
    public func isCurrentWorkingDirectoryValid()->Bool {
        return TFSClient.isDirectoryTFSCompatible(self.workingDirectory)
    }
    
    public func areUsernameAndPasswordValids()->Bool {
        if(username.isEmpty || password.isEmpty) {
            return false;
        }
        
        return true;
    }
    
    public func canCommit()->Bool {
        return isCurrentWorkingDirectoryValid() //TODO: Check if there are staged files
    }
    
    
    //Static funcs
    //-----------------------------------
    public static func isDirectoryTFSCompatible(workingDirectoryPath:String)->Bool {
        return GitTfAdapter.isWorkingDirectoryValid(workingDirectoryPath)
    }
    
    
    //Privates funcs
    //-----------------------------------
    private func setCurrentCommand(commandType:TFSCommandType, completionHandler:(withSuccess:Bool) -> ()) -> Bool
    {
        if(self.currentTFSCommand == TFSCommandType.None) {
            self.tfsCommandCompletion = completionHandler
            self.currentTFSCommand = commandType
            
            return true
        }
        
        NSLog("Cannot execute command \"" + commandType.description + "\" because the command \"" + self.currentTFSCommand.description + "\" is already being executed")
        
        return false
    }
    
    
    //GitTfAdapterDelegate impl
    //-----------------------------------
    func commandDidStart(command:TFSCommandType) {
        if let delegate = self.delegate {
            delegate.commandDidStart(command)
        }
    }
    
    func commandDidStop(withSuccess:Bool, command:TFSCommandType) {
        
        if let completionHandler = self.tfsCommandCompletion
        {
            completionHandler(withSuccess)
        }
        
        if let delegate = self.delegate {
            delegate.commandDidStop(withSuccess, command:command)
        }
        
        self.currentTFSCommand = TFSCommandType.None
        self.tfsCommandCompletion = nil
    }
    
    func progressInfo(info: String) {
        
        if let delegate = self.delegate {
            delegate.tfsClientProgressUpdate(info)
        }
        
    }
    
    func errorOccured(command:TFSCommandType, errorReason: String) {
        if let delegate = self.delegate {
            delegate.tfsClientErrorOccured(command, errorReason:errorReason)
        }
    }
    
    func getPassword()->String{
        return self.password
    }
    func getUsername()->String{
        return self.username
    }
    
}



